# -*- coding: utf-8 -*-
import datetime
import json
import time

from celery import Celery
from celery.utils.log import get_task_logger
from flask import Flask, Blueprint, Response
from flask_mail import Message

from . import db
from . import logger
from .endpoints import urls
from .ext import orm, mail


class DateTimeEncoder(json.JSONEncoder):

    def _parse_datetime(self, obj):
        return time.mktime(obj.timetuple())

    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            return self._parse_datetime(obj)
        else:
            return json.JSONEncoder.default(self, obj)


class AutoJSONfy(Response):

    default_mimetype = 'application/json'

    @classmethod
    def force_type(cls, rv, environ=None):
        if isinstance(rv, dict):
            rv = cls(json.dumps(rv, cls=DateTimeEncoder))
        return super(AutoJSONfy, cls).force_type(rv, environ)


app = Flask(__name__)
app.response_class = AutoJSONfy
app.config.from_envvar('API_SETTINGS')

# Email
mail.init_app(app)

# Initial logger
logger.init_app(app)

# Initial db
db.init_app(app)

# Init sqlalchemy orm
orm.init_app(app)

# Celery app
celeryapp = Celery(app.name, broker=app.config['BROKER_URL'])
celeryapp.conf.update(app.config)
celery_logger = get_task_logger(__name__)


def gen_url(name, host=None):
    if host is None:
        backend = app.config.get('BACKEND_API')
    else:
        backend = host
    url = urls[name].rstrip('/')
    return backend + url


@celeryapp.task(bind=True, ignore_result=True)
def send_async_email(self, subject, sender, to, cc, mail_data):
    try:
        with app.app_context():
            msg = Message(subject=subject,
                          cc=cc,
                          recipients=to,
                          reply_to='%s@qiyi.com' % sender)
            # msg.html = render_template('mail.html', user=sender, **mail_data)
            msg.html = mail_data
            mail.send(msg)
    except Exception, e:
        celery_logger.error('Executing args: {0.args!r}'.format(self.request))

# API v1.0
api = Blueprint('api', __name__)
from . import vps
from . import vpc
from . import domain

# API v2.0
from .v2 import api as api_v2
from .v2 import vps
from .v2 import operate

# Blueprints
app.register_blueprint(api, url_prefix='/api')
app.register_blueprint(api_v2, url_prefix='/api/v2')


def run(host='0.0.0.0', port=11122):
    app.run(host, port=port)
